﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.Data.OleDb;
using Kn.ALICE;
using Kn.DLMS.Internal;
using Kn.DLMS;
using static Kn.ALICE.GXAliceData;
using WinFormMDI;
using System.Reflection;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {

        internal static GXAliceDevice CurDev;

        public GXHPLCDevice HPLCDev { get; set; }

        #region 私有成员
        int g_iPort;      //下行
        int g_iPortUp;    //上行
        //int    g_DataBit;    //数据位


        public CommProcess commUp = new CommProcess();
        //private string strUn;
        #endregion

        void ComLoad(System.Windows.Forms.ComboBox comBox, string comKey)
        {
            foreach (string vPortName in SerialPort.GetPortNames())
            {
                MyItem comItem1 = new MyItem(vPortName, vPortName);
                comBox.Items.Add(comItem1);
            }
            comBox.DisplayMember = "Text";        //displaymember:前台显示的字段。绑定
            comBox.ValueMember = "Value";         //ValueMember:后台取值的字段。

            if (comBox.Items.Count != 0)
            {
                string strComDown = AppConfigProcess.GetConfigXml(comKey);
                int index = comBox.FindString(strComDown);
                if (index >= 0)
                {
                    comBox.SelectedIndex = index;
                }
                else
                {
                    comBox.SelectedIndex = 0;          //不存在默认选择0
                }
            }
            else
            {
                //label_ComDown.ForeColor = Color.Red;
            }
        }
        public GXAliceData8110 HPLCSeting = new GXAliceData8110(); //模块配置


        void LedUIInit()
        {
            pictureBox_LedRun.Image = imageListLed.Images["LED_Off1.png"];
            pictureBox_Down.Image = imageListLed.Images["LED_Off1.png"];
            pictureBox_Up.Image = imageListLed.Images["LED_Off1.png"];
        }


        public int RunTime;

        int richTextBox_Message_Len;

        private void timer_Power_Tick(object sender, EventArgs e)
        {
            if(richTextBox_Message_Len != richTextBox_Message.Text.Length)
            {
                //richTextBox_Message_Len = richTextBox_Message.Text.Length;
                //richTextBox_Message.Focus();
                //richTextBox_Message.Select(richTextBox_Message.Text.Length, 0);
                //richTextBox_Message.ScrollToCaret();
            }

            LedPowerTick();
        }
        void LedPowerStart()
        {
            RunTime = 0;
            timer_Power.Start();
            pictureBox_LedRun.Image = imageListLed.Images["LED_GreenOn.png"];
        }
        void LedPowerStop()
        {
            timer_Power.Stop();
            pictureBox_LedRun.Image = imageListLed.Images["LED_Off1.png"];
       
        }

        void LedPowerTick()
        {
            RunTime++;
            if (RunTime % 2 == 0)
            {
                pictureBox_LedRun.Image = imageListLed.Images["LED_Off1.png"];
            }
            else
            {
                pictureBox_LedRun.Image = imageListLed.Images["LED_GreenOn.png"];
            }


        }

        public Form1()
        {
            InitializeComponent();
 

            ComLoad(comboBox_ComDown, "COM");           //加载下行载波模块串口
            comboBox_ComUp.Items.Add("不启用");
            ComLoad(comboBox_ComUp, "COM_UP_SPLN");     //加载上行HDLC串口

            #region 实例下行串口media
            CommProcess comm = new CommProcess(); 
            GetConfig();
            comm.ParserHandler = ParserHandlerUI;
            comm.ReceiveHandler = ReceiveData;
            #endregion

            #region  实例HPLCDev 下行
            CurDev = new GXAliceDevice(null, HPLCSeting);
            HPLCDev = new GXHPLCDevice(comm);  
            HPLCDev.communicator.client.GXSeting(HPLCSeting);
            #endregion

            #region 上行
            commUp.ParserHandler = UpParserHandlerUI;
            //commUp.OpenPort(g_iPort, 19200, 8, 1, "N");
            #endregion


            toolStripButton_Stop.Enabled = false;
            LedUIInit();
        }

        public class MyItem
        {
            private string _Text = "";     //属性1 名字
            private string _Value = "";    //属性2 名字id

            public MyItem(string Text, string Value)   //构造
            {
                _Text = Text;
                _Value = Value;
            }

            public string Text { get { return this._Text; } set { this._Text = value; } }       //名称
            public string Value { get { return this._Value; } set { this._Value = value; } }    //值
        }

        private void GetConfig()   //读取配置文件串口配置,写到全局字段
        {
            //获取波特率
            //g_iBaudRate = 19200;    //波特率
            //g_Parity = "E";        //校验位
            //g_Parity = "N";        //校验位
            //g_StopBit = 1;         //停止位
            //g_DataBit = 8;         //数据位

            string comxx = comboBox_ComDown.Text;
            string id;
            int len = 1;
            if (comxx.Length > 4)
            {
                len = 2;
            }
            if (comxx.Length < 3) return;
            id = comxx.Substring(3, len);
            g_iPort = Convert.ToInt32(id);


            comxx = comboBox_ComUp.Text;
            if(comxx == "不启用")
            {
                g_iPortUp = -1;
            }
            else
            {
                len = 1;
                if (comxx.Length > 4)
                {
                    len = 2;
                }
                if (comxx.Length < 3) return;
                id = comxx.Substring(3, len);
                g_iPortUp = Convert.ToInt32(id);
            }
        }


        public delegate void DelegateDisplayInfotool(int DownTxCnt, int DownRxCnt);

        void DisplayInfotoolStripStatusLabel(int DownTxCnt, int DownRxCnt)
        {
                // 在 UI 线程上执行控件操作
            if (InvokeRequired)
            {
                // 如果当前线程不是 UI 线程，使用 BeginInvoke 方法将操作委托到 UI 线程上执行
                BeginInvoke(new DelegateDisplayInfotool(DisplayInfotoolStripStatusLabel), DownTxCnt, DownRxCnt);
            }
            else
            {
                toolStripStatusLabel_TxCnt.Text = DownTxCnt.ToString();
                toolStripStatusLabel_RxCnt.Text = DownRxCnt.ToString();
            }
        }
        
        
        void DisplayInfo(string info, Color showColor)
        {
            if (richTextBox_Message.InvokeRequired)
            {
                richTextBox_Message.Invoke(new Action(() =>
                {
                    this.richTextBox_Message.SelectionColor = showColor;
                    richTextBox_Message.AppendText(info + "\r\n");  //打印发送帧
                }));
            }
            else
            {
                this.richTextBox_Message.SelectionColor = showColor;
                richTextBox_Message.AppendText(info + "\r\n");  //打印发送帧
            }
        }
        
        
        private void SetStateResultValue(string strResult)
        {
            Application.DoEvents();
            //toolStripStatusLabel1.Text = strResult;
            Application.DoEvents();
        }

        private void SetErrorMessage(string strEx)
        {
            MessageBox.Show(strEx);
        }


        #region 界面报文解析功能
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            ParserHandler1(); //手动解析
        }
 
        void ParserHandler1()
        {
            GXAliceParser reply = new GXAliceParser();
            try
            {
                if (textBox_HDLCFrame.Text.Length < 10) return;
                string HdlcFrame = textBox_HDLCFrame.Text.Replace("\\", "");

                HdlcFrame = HdlcFrame.Replace("\r", "");
                HdlcFrame = HdlcFrame.Replace("\t", "");
                HdlcFrame = HdlcFrame.Replace("\n", "");
                HdlcFrame = HdlcFrame.Replace(" ", "");
                HdlcFrame = HdlcFrame.Replace(":", "");
                HdlcFrame = HdlcFrame.Replace(",", "");
                HdlcFrame = HdlcFrame.Replace("输入解析报文:", "");

                byte[] tmp = GXCommon.HexToBytes(HdlcFrame);

                GXByteBuffer HDLCFrame = new GXByteBuffer();
                HDLCFrame.Set(tmp);

                
                bool result = CurDev.communicator.client.Parser(tmp, reply);
                string strDir = "";
                Color frameColor;
                if (reply.DIR == true)
                {
                    strDir = "接收CU通信模块<=DE电表:";
                    frameColor = ColorRxFrame;
                }
                else
                {
                    strDir = "发送CU通信模块=>DE电表:  ";
                    frameColor = ColorTxFrame;
                }

                if (result == false)
                {
                    frameColor = Color.Red;
                }

                DisplayInfo("----------------------------", frameColor);
                DisplayInfo(strDir + reply.FrameString, frameColor);
                DisplayInfo("-----------------------------", frameColor);
                DisplayInfo("***解析结果如下***:", frameColor);
                DisplayInfo(reply.FrameResult, ColorText);

                richTextBox_Message.Focus();
                richTextBox_Message.Select(richTextBox_Message.Text.Length, 0);
                richTextBox_Message.ScrollToCaret();
            }
            catch
            {
                DisplayInfo(reply.FrameString, Color.Red);
                DisplayInfo("-----------------------------", Color.Red);
                DisplayInfo("***解析结果如下***:", Color.Red);
                DisplayInfo(reply.FrameResult, Color.Red);
            }

        }
        #endregion


        private void richTextBox_Message_TextChanged(object sender, EventArgs e)
        {
            //richTextBox_Message.Focus();
            //richTextBox_Message.Select(richTextBox_Message.Text.Length, 0);
            //richTextBox_Message.ScrollToCaret();
        }

      
        #region HPLC
        public ALICE_Chart AliceChat = new ALICE_Chart();
        #region HPLC 下行
        public Color ColorTxFrame = Color.DeepSkyBlue;
        public Color ColorRxFrame = Color.Yellow;
        public Color ColorOK      = Color.LightGreen;
        public Color ColorFAIL = Color.Red;
        public Color ColorText = Color.Transparent;

        public Color ColorActionInfo = Color.BurlyWood;// Color.DeepPink;
        public Color ColorActionInfoText =  Color.DeepPink;
        public string strActionInfo = "==========================";

        public string strSeg = "---------------------------------------------------------------";
        public string strPage = "***************************";

        public GXAliceParser g_reply = new GXAliceParser();
        public delegate void ParserHandlerDelegate(byte[] AliceFrame);

        private void ReceiveData(byte[] AliceFrame)
        {
            AliceChat.EnqueueData(AliceFrame);
        }

        private void ParserHandlerUI(byte[] AliceFrame)
        {
            // 在 UI 线程上执行控件操作
            if (InvokeRequired)
            {
                // 如果当前线程不是 UI 线程，使用 BeginInvoke 方法将操作委托到 UI 线程上执行
                BeginInvoke(new ParserHandlerDelegate(ParserHandlerUI), AliceFrame);
            }
            else
            {
                // 如果当前线程是 UI 线程，直接执行操作！！！！！！！！！！！

                bool result = CurDev.communicator.client.Parser(AliceFrame, g_reply);
                string strDir = "";
                Color frameColor;
                if (g_reply.DIR == true)
                {
                    strDir = "接收通信模块CU<=电表DE:";
                    frameColor = ColorRxFrame;// Color.DarkGreen;
                    //EventTxRx("RX");
                }
                else
                {
                    strDir = "发送通信模块CU=>电表DE:  ";
                    frameColor = ColorTxFrame;// Color.Blue;
                    //EventTxRx("TX");
                }

                if (result == false)
                {
                    frameColor = Color.Red;
                }

                

                DisplayInfo(strSeg, frameColor);
                DisplayInfo(GXCommon.GetNowTime() + strDir + g_reply.FrameString, frameColor);
                DisplayInfo(strSeg, frameColor);
                DisplayInfo(g_reply.FrameResult, ColorText);
                
            }
        }
 

      

        void OpenDeviceCom()
        {
            int bps = Convert.ToInt32(AppConfigProcess.GetConfigXml("BpsDown"));
            HPLCDev.Media.OpenPort(g_iPort, bps, 8, 1, "N");

        }

        void CloseDeviceCom()
        {
            //HPLCDev.Media.OpenPort(g_iPort, 9600, 8, 1, "N");
            HPLCDev.Media.ClosePort(g_iPort);
        }

        void UI_DisplayInfo(string cmd)
        {
            DisplayInfo(strActionInfo, ColorActionInfo);
            DisplayInfo(cmd + "  " + GXCommon.GetNowTime1(), ColorActionInfoText);
            DisplayInfo(strActionInfo, ColorActionInfo);
        }

        void UI_DisplayInfo(string cmd, string info, bool result)
        {

            if(result == true)
            {
                DisplayInfo(strActionInfo, ColorActionInfo);
                DisplayInfo(cmd + "成功" + " " + info,  ColorOK);
                DisplayInfo(strActionInfo, ColorActionInfo);
            }
            else
            {
                DisplayInfo(strActionInfo, ColorActionInfo);
                DisplayInfo(cmd + "失败" + " "+ info, ColorFAIL);
                DisplayInfo(strActionInfo, ColorActionInfo);
            }

        }

        public delegate void CallEventHandler(GXAliceData sender, Exception ex);

        void CU_ReportResponse(GXAliceData sender, Exception ex)
        {
            if(ex == null)
            {
                GXAliceDataReply DataReply = (GXAliceDataReply)sender;

                if(DataReply.Result == ResponseType.Success)
                {
                    UI_DisplayInfo("CU报告", "", true);
                }
                else
                {
                    UI_DisplayInfo("CU报告", ",原因如上解析结果", false);
                }
                
            }
            else
            {
                UI_DisplayInfo("CU报告", "," + ex.Message, false);
            }
        }

        void DE_Report(GXAliceData sender, Exception ex)
        {
            if (ex == null)
            {
                GXAliceData0120 Data = (GXAliceData0120)sender;
                
                UI_DisplayInfo("DE报备", "DE地址" + Data.meterAddress, true);
            }
            else
            {
                UI_DisplayInfo("DE报备", "," + ex.Message, false);
            }
        }

        void CU_HeartResponse(GXAliceData sender, Exception ex)
        {
            if (ex == null)
            {
                UI_DisplayInfo("心跳", "", true);
            }
            else
            {
                UI_DisplayInfo("心跳", "," + ex.Message, false);
            }
        }
        void Connect()
        {

            UI_DisplayInfo("☎  CU报告");
            HPLCDev.communicator.CU_Report(CU_ReportResponse);

            UI_DisplayInfo("✪  等待DE报备");
            HPLCDev.communicator.CU_Listening(DE_Report);

        }

        void Heart()
        {
            UI_DisplayInfo("❤  心跳");
            HPLCDev.communicator.CU_Heart(CU_HeartResponse);
        }


        void CU_SendResponse(GXAliceData sender, Exception ex)
        {
            if (ex == null)
            {
                if(sender.IsAck == true)
                {
                    GXAliceDataReply DataReply = (GXAliceDataReply)sender;
                    if (DataReply.Result == ResponseType.Success)
                    {
                        UI_DisplayInfo("✉   转发", "", true);
                    }
                    else
                    {
                        UI_DisplayInfo("✉  SPLN交互", ",原因如上解析结果", false);
                    }
                }
                else
                {
                    GXAliceData0304 Reply = (GXAliceData0304)sender;


                    string FrameString = Reply.content.GetString(Reply.content.Size);
                    Reply.content.Position = 0;
                    byte[] tmp = Reply.content.Remaining();

                    
                    //上行发送
                    UpDisplayInfo(GXCommon.GetNowTime1() + " <== " + FrameString, Color.DarkGreen);
                    commUp.Send(tmp);
                    UI_DisplayInfo("✉    SPLN交互", "", true);
                }

            
            }
            else
            {
                UI_DisplayInfo("✉    SPLN交互", "," + ex.Message, false);
            }
        }

        void Send(GXByteBuffer HDLCFrame)
        {

            DisplayInfo("\r\n", ColorActionInfo);
            UI_DisplayInfo("✉   SPLN数据交互");
            HPLCDev.communicator.CU_Send(HDLCFrame, CU_SendResponse);  //直接发送
        }

       

        #region 线程列表
        Thread ThreadDownTask;  //下线线程
        Thread ThreadUpTask;    //上行线程
        #endregion

        #region 下行任务
        int DownRxCnt = 0;
        int DownTxCnt = 0;


        //监听上报
        void notifications()
        {

        }

        void read()
        {

        }
        
 
        void at_obj_process()
        {
            notifications();
            read();
            //at_work_process(ai);   //作业


        }



        void TaskDown()
        {

            OpenDeviceCom();  //打开串口
            Connect();        //连接电表
      
            //处理心跳、上报、数据转发
            while(true)
            {

                // 检查队列是否为空
                if (AliceChat.IsQueueEmpty() == false)
                {
                    DownRxCnt++;
                    byte [] AliceFrame = AliceChat.DequeueFrame();


                    bool result = CurDev.communicator.client.Parser(AliceFrame, g_reply);
                    string strDir = "";
                    Color frameColor;
                    if (g_reply.DIR == true)
                    {
                        strDir = "接收CU通信模块<=DE电表:";
                        frameColor = ColorRxFrame; //Color.DarkGreen;
                                                   //EventTxRx("RX");
                    }
                    else
                    {
                        strDir = "发送CU通信模块=>DE电表:  ";
                        frameColor = ColorTxFrame; //Color.Blue;
                                                   //EventTxRx("TX");
                    }

                    if (result == false)
                    {
                        frameColor = Color.Red;
                    }


                    // 在 UI 线程上调用更新方法
                    Invoke((MethodInvoker)(() =>
                    {
                        // 调用更新方法
                        DisplayInfotoolStripStatusLabel(DownTxCnt, DownRxCnt); //打印发送帧条数,打印接收帧条数到label
                        DisplayInfo(strSeg, frameColor);
                        DisplayInfo(DownRxCnt.ToString() + " " + GXCommon.GetNowTime() + strDir + g_reply.FrameString, frameColor); //打印帧报文到richbox
                        DisplayInfo(strSeg, frameColor);
                        DisplayInfo(g_reply.FrameResult, ColorText); //打印帧解析内容到richbox
         
                    }));

                }
                
                //心跳  监听上报 转发任务
                //Heart();
                //Thread.Sleep(60000);
            }
            Thread.Sleep(3000);

        }
        #endregion

        #region 上行任务
        void TaskUp()
        {
            try
            {
                commUp.OpenPortUp(g_iPortUp, 9600, 8, 1, "N");  //打开上行串口接收
                GXByteBuffer SendBuf = new GXByteBuffer();
                while (true)
                {
                    if (EventFlagUp == true)
                    {
                        EventFlagUp = false;
                        SendBuf.Clear();
                        SendBuf.Set(UpFrameBuff.Remaining());
                        string FrameString = UpFrameBuff.GetString(UpFrameBuff.Size); 
                        UpDisplayInfo(GXCommon.GetNowTime1() + " ==> " + FrameString, Color.Blue);  //接受数据
                        Send(SendBuf);  //转发给下行
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region 用户UI操作处理
        private void toolStripButton_Start_Click(object sender, EventArgs e)
        {
            if (sender.ToString() == "开始")
            {
                toolStripButton_Stop.Enabled = true;
                toolStripButton_Start.Enabled = false;
                LedPowerStart();
                Start();  //创建任务执行线程,并开始线程,执行任务
            }
        }
        private void toolStripButton_Stop_Click(object sender, EventArgs e)
        {
            toolStripButton_Stop.Enabled = false;
            toolStripButton_Start.Enabled = true;
            //停止线程
            CloseDeviceCom();
            LedPowerStop();
            LedUIInit();
            Stop();
        }

        //开始按钮单击处理
        public void Start()
        {
            ThreadDownTask = new Thread(TaskDown);
            ThreadDownTask.IsBackground = true;       //置这个线程为后台线程
            ThreadDownTask.Start();

            ThreadUpTask = new Thread(TaskUp);
            ThreadUpTask.IsBackground = true;          //置这个线程为后台线程
            ThreadUpTask.Start();

        }

        //停止按钮单击处理
        public void Stop()
        {

            //MainTaskStatus = 3;  //通知结束任务
            //MessageBox.Show("测试终止结束！");

        }

        private void toolStripButton_Config_Click(object sender, EventArgs e)
        {
            FormConfig dg = new FormConfig(this);
            dg.ShowDialog();
        }

        #endregion


        #endregion

        #region 上行HPLC
        void UpDisplayInfo(string info, Color showColor)
        {
            if (richTextBoxUp.InvokeRequired)
            {
                richTextBoxUp.Invoke(new Action(() =>
                {
                    this.richTextBoxUp.SelectionColor = showColor;
                    richTextBoxUp.AppendText(info + "\r\n");  //打印发送帧
                }));
            }
            else
            {
                this.richTextBoxUp.SelectionColor = showColor;
                richTextBoxUp.AppendText(info + "\r\n");  //打印发送帧
            }
        }


        GXByteBuffer UpFrameBuff = new GXByteBuffer();
        bool EventFlagUp = false; 

        public delegate void UpParserHandlerDelegate(byte[] HDLCFrame);
        private void UpParserHandlerUI(byte[] HDLCFrame)  //串口
        {
            try
            {
                if (InvokeRequired)
                {
                    // 如果当前线程不是 UI 线程，使用 BeginInvoke 方法将操作委托到 UI 线程上执行
                    BeginInvoke(new UpParserHandlerDelegate(UpParserHandlerUI), HDLCFrame);
                }
                else
                {
                    if (EventFlagUp == false)  //上行监听
                    {
                        UpFrameBuff.Clear();
                        UpFrameBuff.Set(0, HDLCFrame);
                        EventFlagUp = true;  //通知处理数据
                    }

                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
       
           
        }
        #endregion


 
     

        private void richTextBoxUp_TextChanged(object sender, EventArgs e)
        {
            richTextBoxUp.Focus();
            richTextBoxUp.Select(richTextBoxUp.Text.Length, 0);
            richTextBoxUp.ScrollToCaret();
        }

        #endregion

        public void GetConfigPara()
        {
            comboBox_ComDown.Text = AppConfigProcess.GetConfigXml("COM");
            comboBox_ComUp.Text   = AppConfigProcess.GetConfigXml("COM_UP_SPLN");
            GetConfig();
        }

        private void toolStripButton_Clear_Click(object sender, EventArgs e)
        {
            richTextBox_Message.Clear();
            richTextBoxUp.Clear();
            DownRxCnt = 0;
            DownTxCnt = 0;
            DisplayInfotoolStripStatusLabel(DownRxCnt, DownTxCnt);

        }

        private void richTextBox_Message_Click(object sender, EventArgs e)
        {
            richTextBox_Message.Focus();
            richTextBox_Message.Select(richTextBox_Message.Text.Length, 0);
            richTextBox_Message.ScrollToCaret();
        }
    }
}
